home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
401-425
/
disk_405
/
gifmachine
/
sources
/
24to12.c
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
4KB
|
168 lines
/* Copyright 1990 by Christopher A. Wichura.
See file GIFMachine.doc for full description of rights.
*/
#include "GIFMachine.h"
extern struct GIFdescriptor gdesc;
EXTERNBITPLANE;
/* since both MasterColourTable and the PaletteBuf are the same size and
type we will define MCT to be the PaletteBuf to cut down on static
memory declarations */
#define MasterColourTable PaletteBuf
extern UBYTE MasterColourTable[MAXCOLOURS];
static UWORD TotalColours;
extern BYTE *CurrentLineErr[3];
extern BYTE *LastLineErr[3];
extern char *AbortMsg;
#define MAXERR 2
void ReduceTo12(void)
{
register UWORD x;
register UWORD y;
PutStr("...Reducing palette to 12 bits.\n......Line ");
TotalColours = 0;
memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
for (y = 0; y < gdesc.gd_Height; y++) {
MyPrintf("%5ld", y);
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
for (x = 0; x < gdesc.gd_Width; x++)
PutValue(x, y, AddColour(&BitPlane[y][x]));
PutStr("\x9B" "5D");
}
MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
}
void DitherTo12(void)
{
register UWORD x;
register UWORD y;
register int RedErr;
register int GreenErr;
register int BlueErr;
BYTE **cerr, **lerr, **terr;
struct RGB rgb;
PutStr("...Dithering palette to 12 bits.\n......Setup");
TotalColours = 0;
memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
cerr = (BYTE **)&CurrentLineErr[0];
lerr = (BYTE **)&LastLineErr[0];
/* the top, left and right borders will be used unmodified */
for (x = 0; x < gdesc.gd_Width; x++)
PutValue(x, 0, AddColour(&BitPlane[0][x]));
for (y = 1; y < gdesc.gd_Height; y++) {
PutValue(0, y, AddColour(&BitPlane[y][0]));
PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
}
/* since the error tables are alloced with MEMF_CLEAR we won't bother
to clear them here. instead, we just hit the main loop */
PutStr("\x9B" "5DLine ");
for (y = 1; y < gdesc.gd_Height; y++) {
MyPrintf("%5ld", y);
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
for (x = 1; x < (gdesc.gd_Width - 1); x++) {
rgb = BitPlane[y][x];
RedErr = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
BlueErr = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
RedErr >>= 4;
GreenErr >>= 4;
BlueErr >>= 4;
/* now we add the errors into the colour we want. if this would push
us over 255 (and thus out of range) we subtract the error out so
that we still see some dithering instead of washing out the area. */
if (rgb.rgb_Red + RedErr > 255)
rgb.rgb_Red -= RedErr;
else
rgb.rgb_Red += RedErr;
if (rgb.rgb_Green + GreenErr > 255)
rgb.rgb_Green -= GreenErr;
else
rgb.rgb_Green += GreenErr;
if (rgb.rgb_Blue + BlueErr > 255)
rgb.rgb_Blue -= BlueErr;
else
rgb.rgb_Blue += BlueErr;
PutValue(x, y, AddColour(&rgb));
RedErr = (int)rgb.rgb_Red - (int)(rgb.rgb_Red & 0xF0);
GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
BlueErr = (int)rgb.rgb_Blue - (int)(rgb.rgb_Blue & 0xF0);
if (RedErr > MAXERR)
RedErr = (RedErr * 3) >> 2;
if (GreenErr > MAXERR)
GreenErr = (GreenErr * 3) >> 2;
if (BlueErr > MAXERR)
BlueErr = (BlueErr * 3) >> 2;
cerr[0][x] = RedErr;
cerr[1][x] = GreenErr;
cerr[2][x] = BlueErr;
}
terr = lerr;
lerr = cerr;
cerr = terr;
PutStr("\x9B" "5D");
}
MyPrintf("\x9B" "5D%ld total unique colours used.\n", TotalColours);
}
UWORD AddColour(struct RGB *rgb)
{
register UWORD colour;
colour = ((rgb->rgb_Red << 4) & 0xF00) |
(rgb->rgb_Green & 0xF0) |
(rgb->rgb_Blue >> 4);
if (!MasterColourTable[colour]) {
MasterColourTable[colour] = 1;
TotalColours++;
}
return colour;
}